/*
	Source compilation test.
*/

#include "Tests.h"

#ifdef _NOISE_UNIT_TEST

void CompileSource (Source src, EProgram progType)
{
	Program prog = nCreateProgram( progType );
	
	int show_preview = true;
	CHECK_N( nSetProgramInteger( prog, SHOW_IMAGE_PREVIEW, &show_preview, 1 ) );

	CHECK_N( nBuildProgram( prog, src, EBuildOptions( DEFAULT_OPTIONS ) ) );
	
	const uvec2		size( 128, 128 );
	buffer<float>	data( size.Square() );
	CHECK_N( nRenderToMemory( prog, size.x, size.y, 0, 0, 0, R, FLOAT32, data.ptr() ) );

	TPlatform::Delay(5000);
	
	nDeleteProgram( prog );
}


void Compile (Source src)
{
	int		src_count = 0;
	Source	sources[8] = {0};

	CHECK_N( nGetSourceInteger( src, INPUT_SOURCES, &src_count, 1 ) );

	for (uint i = 0; i < Min<uint>( src_count, count_of(sources) ); ++i)
	{
		float val = (float)i;
		sources[i] = nCreateSource( CONSTANT );
		CHECK_N( nSetArgFloat( sources[i], ARG_CONST, &val, 1 ) );
		CHECK_N( nSetArgSource( src, EArgument(SOURCE_0 + i), sources[i] ) );
	}

	CompileSource( src, OPENCL_PROGRAM );
	//CompileSource( src, NATIVE_PROGRAM );

	for (uint i = 0; i < Min<uint>( src_count, count_of(sources) ); ++i)
	{
		nDeleteSource( sources[i] );
	}
}


void SourceCompilationTest ()
{
	int numSources = 0;
	int sourceTypes[256] = {0};

	CHECK_N( nGetContextInteger( CONTEXT_SUPPORTED_SOURCES_COUNT, &numSources, 1 ) );
	CHECK_N( nGetContextInteger( CONTEXT_SUPPORTED_SOURCES, sourceTypes, count_of(sourceTypes) ) );

	for (uint i = 0; i < (uint)numSources; ++i)
	{
		ESource type = (ESource)sourceTypes[i];
		Source	src  = nCreateSource( type );

		switch ( type )
		{
			case CURVE : {
				const float points[4*2] = {	0.1f, 0.5f,
											0.2f, 13.1f,
											0.4f, 5.8f,
											0.8f, 9.1f };
				CHECK_N( nSetArgFloat( src, ARG_ADD_CONTROL_POINTS, points, count_of(points) ) );
				break;
			}

			case TERRACE : {
				const float points[4*2] = {	0.1f, 0.5f,
											0.2f, 13.1f,
											0.4f, 5.8f,
											0.8f, 9.1f };
				CHECK_N( nSetArgFloat( src, ARG_ADD_CONTROL_POINTS, points, count_of(points) ) );
				break;
			}

			case GRADIENT : {
				const float gradient[4*5] = { 0.125f, 0.1f, 0.1f, 0.1f, 0.1f,
											  0.25f,  0.4f, 0.4f, 0.4f, 0.4f,
											  0.5f,   0.7f, 0.7f, 0.7f, 0.7f,
											  1.0f,   1.0f, 1.0f, 1.0f, 1.0f };
				CHECK_N( nSetArgFloat( src, ARG_ADD_COLOR_POINTS, gradient, count_of(gradient) ) );
				break;
			}
		}

		if ( type == SWIZZLE )
			continue;

		Compile( src );
	}
}


void SourceTests()
{
	SourceCompilationTest();
}

#endif	// _NOISE_UNIT_TEST